﻿package tk.mystudio.permission.service;

import java.text.MessageFormat;
import java.util.Collections;
import java.util.List;
import java.util.Observable;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import tk.mystudio.permission.bean.Resource;
import tk.mystudio.permission.bean.Role;
import tk.mystudio.permission.constant.RoleType;
import tk.mystudio.permission.dao.ResourceDao;
import tk.mystudio.permission.dao.RoleDao;
import tk.mystudio.permission.dao.RoleResourceDao;
import tk.mystudio.permission.exception.OperationForbidden;
import tk.mystudio.permission.exception.RoleNameExistedException;

@Service
@Transactional
public class RoleService extends Observable {

	private final Logger logger = LoggerFactory.getLogger(RoleService.class);

	@javax.annotation.Resource
	private RoleDao roleDao;
	@javax.annotation.Resource
	private ResourceDao resourceDao;
	@javax.annotation.Resource
	private RoleResourceDao roleResourceDao;

	@Transactional
	public Role createRole(Role role) throws RoleNameExistedException {
		Assert.notNull(role);
		Assert.notNull(role.getRoleType());
		Role existedRole = new Role();
		existedRole.setName(role.getName());
		if(roleDao.getCount(existedRole)>0) {
			throw new RoleNameExistedException(MessageFormat.format("角色名{0}已经存在", role.getName()));
		}
		roleDao.save(role);
		return role;
	}

	@Transactional
	public Role updateRole(Role role) {
		roleDao.update(role);
		return role;
	}

	@Transactional(readOnly = false)
	public Role getRoleById(int id) {
		return roleDao.get(id);
	}

	@Transactional
	public void deleteRoleById(int id) throws OperationForbidden {
		// -1:指定角色不存在 0:内置角色禁止删除 1:角色删除成功 2:角色删除失败(数据库错误)
		Role role = roleDao.get(id);
		if(RoleType.BUILT_IN_ROLE==role.getRoleType()) {
			logger.error("xxxxxx 尝试删除系统内置角色{}，该操作被阻止", role);
			throw new OperationForbidden("禁止删除系统内置角色");
		}
		roleDao.removeByPhysics(id);
		//TODO 检查此时角色资源表里的相关项是否被删除
		updateGrantAuthrities();
	}

//	@Transactional
//	public List<Account> getAccountListByRoleId(int roleId) {
//		List<Account> result = Collections.emptyList();
////		result.addAll(roleDao.get(roleId))
//		return result;
//	}

	@Transactional
	public List<Resource> getAssignedResourcesByRoleId(int roleId) {
		List<Resource> result = Collections.emptyList();
//		RoleResource roleResource = new RoleResource();
//		roleResource.setRoleId(roleId);
//		List<RoleResource> list = roleResourceDao.getList(roleResource);
//		for(RoleResource rr : list) {
//			result.add(rr.getResource());
//		}
		result.addAll(roleDao.get(roleId).getResources());
		return result;
	}

	@Transactional
	public void grantResources(int roleId, List<Integer> resIdList) {
		// -1:指定角色不存在 1:授权成功 2:授权失败(数据库错误)
		List<Resource> resources = Collections.emptyList();
		if(resIdList!=null && resIdList.size()>0) {
			for(Integer resId : resIdList) {
				resources.add(resourceDao.get(resId));
			}
		}
//		Role role = roleDao.get(roleId);
//		role.setResources(resources);
//		roleDao.update(role);
		//TODO 测试
		updateGrantAuthrities();
	}

	@Transactional
	public List<Role> getAllRoles() {
		return roleDao.getList(null);
	}
	
	//更新授权数据
	private void updateGrantAuthrities() {
		logger.info("====== 刷新授权数据 ======");
		setChanged();
		notifyObservers();	//通知变更
	}
	
	public void setRoleDao(RoleDao roleDao) {
		this.roleDao = roleDao;
	}
	
	public void setResourceDao(ResourceDao resourceDao) {
		this.resourceDao = resourceDao;
	}
	
	public void setRoleResourceDao(RoleResourceDao roleResourceDao) {
		this.roleResourceDao = roleResourceDao;
	}

}
